#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

FILE *input = 0;
FILE *output = 0;
int input_len = 0;
int output_len = 0;
char *input_buff = 0;
char *input_seek = 0;
char *output_buff = 0;
char *output_seek = 0;
char output_name[256] = {0};
int f_comment_line = 0;
int f_comment_block = 0;

#define free_and_close() do { \
if(input) fclose(input); \
if(output) fclose(output); \
if(input_buff) free(input_buff); \
if(output_buff) free(output_buff); \
}  while(0)
#define isend(x) (!(x) || !*(x))
void show_tips()
{
	printf(
		"usage: compress_html[.exe] /some_where/xxx.html\n"
		"output: /some_where/xxx.html.compressed\n"
		);
}

int main(int argc, char **argv)
{
	if (argc != 2) {
		show_tips();
		return -1;
	}
	input = fopen(argv[1],"rb");
	if (!input) {
		perror("fopen");
		return -1;
	}
	fseek(input, 0, SEEK_END);
	input_len = ftell(input);
	fseek(input, 0, SEEK_SET);
	if (!input_len) {
		printf("%s ZERO sized\n", argv[1]);
		free_and_close();
		return 0;
	}
	input_buff = (char *)malloc(input_len + 1);
	if (!input_buff) {
		printf("failed to allocate buff for: %s\n", argv[1]);
		free_and_close();
		return -1;
	}
	memset(input_buff, 0, input_len + 1);

	fread(input_buff, input_len + 1, sizeof(char), input);
	input_buff[input_len] = 0;
	fclose(input);
	input = 0;

	input_seek = strstr(argv[1], ".html");
	if (!input_seek) {
		printf("%s invalid html file name\n");
		free_and_close();
		return -1;
	}
	strncpy(output_name, argv[1], input_seek - argv[1]);
	strcat(output_name, ".html.compressed");

	output = fopen(output_name,"wb");
	if (!output) {
		printf("can't make file: %s\n", output_name);
		free_and_close();
		return -1;
	}

	output_buff = (char *)malloc(input_len + 1);
	if (!output_buff) {
		printf("failed to allocate buff for: %s\n", output_name);
		free_and_close();
		return -1;
	}
	memset(output_buff, 0, input_len + 1);

	input_seek = input_buff;
	output_seek = output_buff;
	while(1){
		if (isend(input_seek))
			break;
		// get rid of continous space
		if (isspace(*input_seek)  
			&& !isend(input_seek+1) 
			&& isspace(input_seek[1]) ) {
			++input_seek;
			continue;
		}
		// get rid of space after something
		if ( !isend(input_seek + 1)
			&&strspn(input_seek, "{};\r\n\t<>(),-+|=*/")
			&& isspace(input_seek[1])) {
			*output_seek++ = *input_seek++;
			while(!isend(input_seek) && isspace(input_seek[0]))
				++input_seek;
			continue;
		}
		// get rid of space before something
		if (isspace(*input_seek) 
			&& !isend(input_seek + 1)
			&& strspn(input_seek + 1, "{};\r\n\t<>(),-+|=*/") ) {
				++input_seek;
				continue;
		}
		// get rid of block comment
		if ( !strncmp(input_seek, "/*",2)) {
			while( strncmp(input_seek,"*/",2 ) )
				++input_seek;
			input_seek+=2;
			continue;
		}
		// get rid of line feed
		if (!strncmp(input_seek, "\n",1) 
			|| !strncmp(input_seek, "\r",1) 
			||	!strncmp(input_seek, "\r\n",2) ) {
			++input_seek;
			continue;
		}
		// get rid of line comment
		if ( !strncmp(input_seek, "//", 2)) {
			f_comment_line = 1;
			while( input_seek
					&& *input_seek 
					&&strncmp(input_seek, "\n",1) 
					&& strncmp(input_seek, "\r\n", 2))
					++input_seek;
			if (!input_seek || !*input_seek) {
				break;
			} else {
				if (!strncmp(input_seek, "\n", 1) )
					++input_seek;
				else
					input_seek += 2;
				continue;
			}
		}
		// no reduce
		*output_seek++ = *input_seek++;
	}
	
	*++output_seek = 0;

	output_len = strlen(output_buff);
	fwrite(output_buff, sizeof(char), output_len, output);
	free_and_close();
	printf("compress rate(before/after): %f(%d/%d)"
		, (float)(input_len - output_len)/input_len
		, input_len, output_len);
	return 0;
}